<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>
    <script>
        // promise 基础使用
        function fetchData() {
            return new Promise((resolve, reject) => {
                setTimeout(() => {
                    if (Math.random() > 0.5) {
                        resolve('大于0.5')
                    } else {
                        reject('小于0.5')
                    }

                }, 500)
            })
        }

        fetchData()
            .then(res => {
                console.log('res1--->>', res1)
                return res
            }, err => {
                console.log('catch error--->>', err)
            })
            .then(res => {
                console.log('res2', res)
            })

        // promise 的基础功能

        // 参考代码：https://github.com/YuetTusi/promise/blob/master/promise.js
        // promise 实现
        class MyPromise {
            constructor(exector) {
                this.state = 'pending' // pending fulfilled rejected
                this.value = undefined
                this.reason = undefined
                this.onResolvedCallbacks = [];
                this.onRejectedCallbacks = [];
                let resolve = (value) => {
                    if (this.state === 'pending') {
                        this.state = 'fulfilled'
                        this.value = value
                        this.onResolvedCallbacks.forEach(fn => fn(value))
                    }
                }

                let reject = (reason) => {
                    if (this.state === 'pending') {
                        this.state = 'reject'
                        this.reason = reason
                        this.onRejectedCallbacks.forEach(fn => fn(reason))
                    }
                }

                try {
                    exector(resolve, reject)
                } catch (err) {
                    reject(err)
                }

            }

            then(onFulFilled, onRejected) {

                const promise2 = new MyPromise((resolve, reject) => {
                    if (this.state === 'fulfilled') {
                        let x = onFulFilled(this.value)
                        resolvePromise(promise2, x, resolve, reject)
                    }
                    if (this.state === 'rejected') {
                        let x = onRejected(this.reason)
                    }
                    if (this.state === 'pending') {
                        if (typeof onFulfilled === 'function') {

                            this.onResolvedCallbacks.push(value => {
                                let x = onFulfilled(value)
                                resolvePromise(promise2, x, resolve, reject);
                            });
                        }
                        if (typeof onRejected === 'function') {
                            this.onRejectedCallbacks.push(value => {
                                let x = onRejected(value)
                                resolvePromise(promise2, x, resolve, reject);
                            });
                        }
                    }
                })

                return promise2

            }
        }

        function resolvePromise(promise2, x, resolve, reject) {
            if (promise2 === x) {
                reject(new TypeError('Promise发生了循环引用'));
            }
            if (x !== null && (typeof x === 'object' || typeof x === 'function')) {
                //可能是个对象或是函数
                try {
                    let then = x.then; //取出then方法引用
                    if (typeof then === 'function') {
                        //then是function，那么执行Promise
                        then.call(x, (y) => {
                            // resolve的结果依旧是promise 那就继续解析
                            resolvePromise(promise2, y, resolve, reject);
                        }, (r) => {
                            reject(r);
                        });
                    } else {
                        resolve(x);
                    }
                } catch (e) {
                    reject(e);
                }
            } else {
                //否则是个普通值
                resolve(x);
            }
        }

        new Promise((resolve,reject)=>{
            setTimeout(()=>{
                resolve('解决了')
            },3000)
        })
        .then((res)=>{
            return new Promise((resolve,reject)=>{
                resolve('12345')
            })
        })
    </script>
</body>

</html>